package com.competition.web.admin.log.impl;

import java.lang.reflect.Field;
import java.util.List;

import org.apache.ibatis.binding.MapperMethod.ParamMap;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Invocation;
import com.competition.web.admin.log.IOperatorLog;
import com.competition.web.admin.service.ILogContentService;
import com.competition.web.admin.service.ILogService;
import com.competition.web.admin.util.SpringBeanUtil;
import com.competition.web.entity.Log;
import com.competition.web.entity.LogContentWithBLOBs;

public class InsertLog extends AbstractLog implements IOperatorLog {

	@Override
	public Integer callBack(Object param, BoundSql boundSql, MappedStatement mappedStatement, Invocation invocation) {
		String tableName = this.getTableName(boundSql);
		if (this.recordLog(tableName)) {
			return 1;
		}

		Object[] data = this.parseData(param);

		Field[] fields;

		Class<?> target;

		ILogService logService = SpringBeanUtil.getBean(ILogService.class);

		// 标记是否已执行原来的方法
		int flag = 0;
		
		List<LogContentWithBLOBs> logContents;

		try {
			
			// 执行原来的操作
			invocation.getMethod().invoke(invocation.getTarget(), invocation.getArgs());
			
			ILogContentService logContentService = SpringBeanUtil.getBean(ILogContentService.class);
			
			flag = 1;
			
			Object idValue, insert;
			
			ParamMap<?> paramMap;
			
			for (int i = 0; i < data.length; i++) {

				insert = data[i];
				
				target = data[i].getClass();
				
 				
				
				
				Field idField = target.getDeclaredField("id");

				if (param instanceof ParamMap) {
					idValue = this.getPropertyValue(idField.getName(), target, insert);
				} else {
					idValue = this.getPropertyValue(idField.getName(), target, param);
				}
				
				
				Log log = new Log();
				
				log.setTableId(Long.valueOf(idValue.toString()));

				/* int status = */logService.insertParse(log, tableName, (byte) 0);

				fields = target.getDeclaredFields();
				
				if (param instanceof ParamMap) {
					logContents = this.parseSingleData(fields, tableName, target, insert, log.getId());
				} else {
					logContents = this.parseSingleData(fields, tableName, target, param, log.getId());
				}
				
				
				
				logContentService.batchInsert(logContents.stream().toArray(LogContentWithBLOBs[]::new));
			}
			
			return 0;

		} catch (Exception e) {
			e.printStackTrace();
			return flag == 1 ? 1: 0; 
		}
	}
	
	protected LogContentWithBLOBs parseContentWithBLOBs(LogContentWithBLOBs content, Object oldValue, Object newValue) {
		
		content.setValue(oldValue.toString());
		
		content.setCurrentValue(newValue.toString());
		
		return content;
	}
}
